﻿using System.Linq;
using System.Linq.Expressions;
using Simple.Common.Authentication;
using Simple.Repository.Models.ClassRoom;
using Simple.Services.System.FileInfo;

namespace Simple.Services.System
{
    public class ClassAlbumService : BusinessBaseService
    {
        private readonly SimpleDbContext _context;
        private readonly CacheService _cacheService;
        private readonly FileInfoService _fileInfoService;

        public ClassAlbumService(SimpleDbContext context,
                           ISimpleService services,
                           CacheService cacheService,
                           FileInfoService fileInfoService) : base(services)
        {
            _context = context;
            _cacheService = cacheService;
            _fileInfoService = fileInfoService;
        }

        public async Task<ClassAlbumOutputModel> GetAsync(Guid? classAlbumId)
        {
            if (!classAlbumId.HasValue)
            {
                throw AppResultException.Status409Conflict("参数错误,班级相册Id参数不能为Null!");
            }
            var classAlbumInfo = await _context.Set<ClassAlbum>().Include(c => c.Images).FirstOrDefaultAsync(c => c.Id == classAlbumId);

            if (classAlbumInfo == null)
            {
                throw AppResultException.Status409Conflict("未找到班级相册相关数据!");
            }

            var outResult = MapperHelper.Map<ClassAlbumOutputModel>(classAlbumInfo);
            if (!string.IsNullOrWhiteSpace(classAlbumInfo.ChildId))
            {
                outResult.ChildIdList = classAlbumInfo.ChildId.Split(',').ToList();
            }

            return outResult;
        }

        public async Task<PageResultModel<ClassAlbumOutputModel>> GetPageAsync(ClassAlbumQueryPageInputModel input)
        {
            if (_currentUser == null)
            {
                throw AppResultException.Status409Conflict("登录已过期,请重新登录!");
            }
            var result = new PageResultModel<ClassAlbumOutputModel>();
            var query = await OrganizationFilter(_context.Set<ClassAlbum>().Include(c => c.Images));
            if (input.IsParent)
            {
                var childId = _currentUser?.FindClaimValue(SimpleClaimTypes.ChildId);
                query = query.Where(p => p.ChildId.Contains(childId) || !p.ClassId.HasValue);
            }
            else
            {
                var classIdList = new List<string>();
                var currentClassAuthorizationList = await GetClassAuthorizationInfo();
                if (currentClassAuthorizationList != null && currentClassAuthorizationList.Any())
                {
                    classIdList = currentClassAuthorizationList.Select(c => c.Id.ToString() ?? string.Empty).Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
                }

                query = query.Where(p => classIdList.Contains(p.ClassId.ToString()) || !p.ClassId.HasValue);
                if (input.ClassId.HasValue)
                {
                    query = query.Where(p => p.ClassId == input.ClassId);
                }

                if (!string.IsNullOrEmpty(input.ContentKey))
                {
                    query = query.Where(m => m.Tags.Contains(input.ContentKey));
                }
                if (input.ChildId.HasValue)
                {
                    query = query.Where(p => p.ChildId.Contains(input.ChildId.Value.ToString()));
                }
            }

            // 排序
            query = query.OrderByDescending(m => m.CreatedTime);

            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.Page(input.PageNo, input.PageSize);
            var classAlbumOutResultList = await query.ToListAsync();
            result.Rows = MapperHelper.Map<List<ClassAlbumOutputModel>>(classAlbumOutResultList);
            if (classAlbumOutResultList != null && classAlbumOutResultList.Any())
            {
                var lstUser = await _context.Set<SysUser>().ToListAsync();
                var lstClass = await _context.Set<SysClasses>().ToListAsync();
                result.Rows?.ForEach(item =>
                {

                    if (!string.IsNullOrWhiteSpace(item.ChildId))
                    {
                        item.ChildIdList = item.ChildId.Split(',').ToList();
                    }
                    var classes = lstClass.FirstOrDefault(p => p.Id == item.ClassId);
                    item.ClassName = classes?.Name;
                    var user = lstUser.FirstOrDefault(p => p.Id == item.CreatedUserId);
                    item.CreateUserName = user?.Name;
                });
            }

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }

        private string GetFileSize(long size)
        {
            var num = 1024.00;
            if (size < num)
                return size + " B";
            if (size < Math.Pow(num, 2))
                return (size / num).ToString("f2") + " KB";
            if (size < Math.Pow(num, 3))
                return (size / Math.Pow(num, 2)).ToString("f2") + " MB";
            if (size < Math.Pow(num, 4))
                return (size / Math.Pow(num, 3)).ToString("f2") + " GB";
            return (size / Math.Pow(num, 4)).ToString("f2") + " TB";
        }

        public async Task<int> DeleteAsync(List<Guid?> ids)
        {
            if (ids == null || !ids.Any())
            {
                throw AppResultException.Status409Conflict("参数错误,班级相册Id参数不能为Null!");
            }

            var classAlbumOutResultList = await _context.Set<ClassAlbum>().Include(c => c.Images)
                .Where(m => ids.Contains(m.Id))
                .ToListAsync();

            if (classAlbumOutResultList == null || !classAlbumOutResultList.Any())
            {
                throw AppResultException.Status404NotFound("未找到班级相册相关数据，删除失败！");
            }

            // 先更新数据库
            _context.RemoveRange(classAlbumOutResultList);
            int ret = await _context.SaveChangesAsync();
            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;
        }

        public async Task<List<ClassAlbumOutputModel>> GetAll()
        {
            var query = await OrganizationFilter(_context.Set<ClassAlbum>());
            var result = await query.ToListAsync();
            if (result == null || !result.Any())
            {
                return new List<ClassAlbumOutputModel>();
            }

            return MapperHelper.Map<List<ClassAlbumOutputModel>>(result) ?? new List<ClassAlbumOutputModel>();
        }

        /// <summary>
        /// 获取当前登录用户授权的班级
        /// </summary>
        /// <returns></returns>
        public async Task<List<ClassesModel>> GetClassAuthorizationInfo()
        {
            var query = await OrganizationFilter(_context.Set<SysClasses>());
            var _IsWhetherTheDirector = false; // 当前是否园长登录
            var lstRole = _context.Set<SysRole>().AsQueryable().Where(p => _currentUser.Roles.Contains(p.Id.ToString())).Select(p => p.Name).ToList();
            if (lstRole.Any(p=>p == "园长"))
            {
                _IsWhetherTheDirector = true;
            }

            if (!_currentUser.IsSuperAdmin && !_IsWhetherTheDirector)
            {
                query = query.Where(c => c.TeacherIds.Contains(_currentUser.UserId.ToString()));
            }

            var authorizationClassList = await query.ToListAsync();
            if (authorizationClassList == null || !authorizationClassList.Any())
            {
                return new List<ClassesModel>();
            }

            return MapperHelper.Map<List<ClassesModel>>(authorizationClassList);
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> AddAsync(ClassAlbumCreateOrUpdateModel input)
        {
            var images = new List<ClassAlbumImage>();
            if (input.ImageList != null && input.ImageList.Any())
            {
                foreach (var file in input.ImageList)
                {
                    var fileId = await _fileInfoService.UploadAsync(new FileInfo.Models.FileInfoInputModel { BusinessType = FileSource.ClassAlbums, File = file });
                    images.Add(new ClassAlbumImage { FiledId = fileId, FileName = file.FileName, FileSize = GetFileSize(file.Length) });
                }
            }
            var task = MapperHelper.Map<ClassAlbum>(input);
            if (input.ChildIdList != null && input.ChildIdList.Any())
            {
                task.ChildId = string.Join(',', input.ChildIdList);
            }
            task.Images = images;
            await _context.AddAsync(task);
            var rte = await _context.SaveChangesAsync();
            return rte > 0;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> MoveAddAsync(ClassAlbumMoveCreateOrUpdateModel input)
        {
            var images = new List<ClassAlbumImage>();
            if (input.ImageIdList != null)
            {
                var files = await _fileInfoService.GetFilesByIdListAsync(input.ImageIdList);
                images = files?.Select(file => new ClassAlbumImage { FiledId = file.Id, FileName = file.FileName, FileSize = file.FileSize ?? String.Empty })?.ToList();
            }
            var task = MapperHelper.Map<ClassAlbum>(input);
            if (input.ChildIdList != null && input.ChildIdList.Any())
            {
                task.ChildId = string.Join(',', input.ChildIdList);
            }
            task.Images = images;
            await _context.AddAsync(task);
            var rte = await _context.SaveChangesAsync();
            return rte > 0;
        }

        /// <summary>
        /// 修改
        /// </summary>
        public async Task<bool> UpdateAsync(ClassAlbumCreateOrUpdateModel input)
        {
            if (!await _context.Set<ClassAlbum>().AnyAsync(p => p.Id == input.Id))
            {
                throw AppResultException.Status500InternalServerError("没有找到该班级相册");
            }
            var task = await _context.Set<ClassAlbum>().Include(p => p.Images).FirstOrDefaultAsync(p => p.Id == input.Id);
            task.Describe = input.Describe;
            if (input.ChildIdList != null && input.ChildIdList.Any())
            {
                task.ChildId = string.Join(',', input.ChildIdList);
            }
            task.Tags = input.Tags;
            task.ClassId = input.ClassId;
            if (input.DeleteImg != null && input.DeleteImg.Any() && task.Images != null && input.DeleteImg.Any())
            {
                var deleteImg = task.Images.Where(p => input.DeleteImg.Contains(p.Id)).ToList();
                _context.RemoveRange(deleteImg);
            }

            var images = new List<ClassAlbumImage>();
            if (input.ImageList != null && input.ImageList.Any())
            {
                foreach (var file in input.ImageList)
                {
                    var fileId = await _fileInfoService.UploadAsync(new FileInfo.Models.FileInfoInputModel { BusinessType = FileSource.ClassAlbums, File = file });
                    images.Add(new ClassAlbumImage { FiledId = fileId, FileName = file.FileName, FileSize = GetFileSize(file.Length) });
                }

                if (images != null && images.Any())
                {
                    task.Images.AddRange(images);
                }
            }
            _context.Update(task);
            int ret = await _context.SaveChangesAsync();
            return ret > 0;
        }

        /// <summary>
        /// 修改
        /// </summary>
        public async Task<bool> MoveUpdateAsync(ClassAlbumMoveCreateOrUpdateModel input)
        {
            if (!await _context.Set<ClassAlbum>().AnyAsync(p => p.Id == input.Id))
            {
                throw AppResultException.Status500InternalServerError("没有找到该亲子计划");
            }
            var task = await _context.Set<ClassAlbum>().FirstOrDefaultAsync(p => p.Id == input.Id);
            task.Describe = input.Describe;
            task.ClassId = input.ClassId;
            if (input.ChildIdList != null && input.ChildIdList.Any())
            {
                task.ChildId = string.Join(',', input.ChildIdList);
            }
            task.Tags = input.Tags;
            var images = new List<ClassAlbumImage>();
            if (input.ImageIdList != null)
            {
                var files = await _fileInfoService.GetFilesByIdListAsync(input.ImageIdList);
                images = files?.Select(file => new ClassAlbumImage { FiledId = file.Id, FileName = file.FileName, FileSize = file.FileSize ?? String.Empty })?.ToList();
            }
            task.Images = images;
            _context.Update(task);
            int ret = await _context.SaveChangesAsync();
            return ret > 0;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<int> DeleteAsync(IEnumerable<Guid> ids)
        {
            var lstTask = await _context.Set<ClassAlbum>()
                .Where(u => ids.Contains(u.Id))
                .ToListAsync();

            _context.RemoveRange(lstTask);
            return await _context.SaveChangesAsync();
        }
    }
}
